package com.vpen.account.demo.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.vpen.account.demo.model.dto.RsaKeyDto;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.stereotype.Component;

import java.time.Duration;


/**
 * 描述 密码传输 公钥加密 私钥解密
 *
 * @author 韦鹏
 * @date 2022/7/19 11:21
 */

@Slf4j
@Component
public class RsaUtils {

    private static RedissonClient REDISSON;


    @Autowired
    private void setRedisson(RedissonClient redisson) {
        REDISSON = redisson;
    }


    private static final String RSA_KEY_PREFIX = "RSA_KEY_PREFIX";


    /***
     * 解密成明文
     * @author 韦鹏
     * @date 2022/7/19 14:54
     * @param passwordEncodeStr 密文
     * @return java.lang.String 明文
     **/
    public static String decryptStr(String passwordEncodeStr) {
        log.debug("passwordEncodeStr:{}", passwordEncodeStr);
        RSA priRsa = new RSA(getRsaKey().getPrivateKey(), null);
        String decryptStr;
        try {
            decryptStr = priRsa.decryptStr(passwordEncodeStr, KeyType.PrivateKey);
        } catch (Exception e) {
            throw new BadCredentialsException("公钥加密错误，请重新使用公钥加密");
        }
        return decryptStr;
    }

    /**
     * 明文加密
     */
    public static String encryptStr(String rawPassword) {
        RSA pubRsa = new RSA(null, getRsaKey().getPublicKey());
        return pubRsa.encryptBase64(rawPassword, KeyType.PublicKey);
    }


    /**
     * 返回公钥
     */
    public static String getRsaPubKey() {
        return getRsaKey().getPublicKey();
    }


    /***
     * 返回一对秘钥
     * @author 韦鹏
     * @date 2022/7/19 15:04
     * @return com.yst.account.login.model.dto.RsaKeyDto
     **/

    private static RsaKeyDto getRsaKey() {
        RBucket<RsaKeyDto> bucket = REDISSON.getBucket(RSA_KEY_PREFIX);
        RsaKeyDto rsaKeyDto = bucket.get();
        if (ObjectUtil.isNull(rsaKeyDto)) {
            rsaKeyDto = new RsaKeyDto();
            bucket.set(rsaKeyDto);
        }
        bucket.expire(Duration.ofMinutes(60));
        return rsaKeyDto;
    }

}
